/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package utils;

import java.io.IOException;
import java.util.LinkedHashMap;
import java.util.Set;
import javax.xml.transform.Source;
import javax.xml.transform.dom.DOMSource;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

public class UpdateValidate {
    private String filePath="";
    private String xsdPath="";
    public static UpdateValidate validator=null;

    public static UpdateValidate Instance(String pathXml,String pathXsd){
        if(validator==null){
            validator=new UpdateValidate();
        }
        validator.setFilePath(pathXml);
        validator.setXsdPath(pathXsd);
        return validator;
    }

    private UpdateValidate() {
    }

    /**
     * @return the filePath
     */
    public String getFilePath() {
        return filePath;
    }

    /**
     * @param filePath the filePath to set
     */
    public void setFilePath(String filePath) {
        this.filePath = filePath;
    }

    /**
     * @return the xsdPath
     */
    public String getXsdPath() {
        return xsdPath;
    }

    /**
     * @param xsdPath the xsdPath to set
     */
    public void setXsdPath(String xsdPath) {
        this.xsdPath = xsdPath;
    }

    public Source updateOnValidateSource(DefaultErrorHandler handler,String elementOnValidatedName, LinkedHashMap<String, String> tableKeys, LinkedHashMap<String, String> properties) throws SAXException, IOException {
        String innerCondition="";
        Set<String> conditionKeys=tableKeys.keySet();
        boolean usedFirst=false;

        for(String key:conditionKeys){
            if(!usedFirst){
                innerCondition+="*[name()='"+key+"']='"+tableKeys.get(key)+"'";
                usedFirst=true;
            }else{
                innerCondition+=" and *[name()='"+key+"']='"+tableKeys.get(key)+"'";
            }
        }
        String condition="";
        if(!innerCondition.isEmpty()){
            condition ="["+innerCondition+"]";
        }
        String expression = "//*[name()='"+elementOnValidatedName+"']"+condition;
        Node doc = XmlUtils.parseDOM(getFilePath());
        Node root = XmlUtils.getOneNode(doc, expression);
        boolean isUpdated = false;
        if (root != null) {
            if (root.getNodeName().equals(elementOnValidatedName)) {
                NodeList propers = root.getChildNodes();
                for (int j = 0; j < propers.getLength(); j++) {
                    Node property = propers.item(j);
                    String proName = property.getNodeName();
                    Set<String> tblKeys = tableKeys.keySet();
                    boolean invalidId=false;
                    for (String key : tblKeys) {
                        if (proName.equals(key)) {
                            String objId = property.getTextContent().trim();
                            if (!objId.equals(tableKeys.get(key))) {
                                invalidId=true;
                                break;
                            }
                        }
                    }

                    if(invalidId){
                        break;
                    }

                    Set<String> keys = properties.keySet();
                    for (String key : keys) {
                        if (proName.equals(key)) {
                            property.setTextContent(properties.get(key));
                            isUpdated = true;
                        }
                    }
                }
            }

            if (isUpdated) {
                Source source = new DOMSource(doc);
                XmlValidate.validate(xsdPath, source, handler);
                return source;
            }
        }
        return null;
    }


}
